
# ifndef __DFX_WAVE_DATA_PROVIDER_H__
# define __DFX_WAVE_DATA_PROVIDER_H__

# include "dfxCore.h"

namespace DFX
{
    enum WAVE_FORMAT
    {
        WAVE_FORMAT_MONO8,
        WAVE_FORMAT_STEREO8,
        WAVE_FORMAT_MONO16,
        WAVE_FORMAT_STEREO16
    };

    class DFX_EXPORT WaveDataProvider
    {
    protected:

        WAVE_FORMAT mWaveFormat;
        UInt32      mChannels;
        UInt32      mSamplesPerSec;
        UInt32      mBitsPerSample;

    public:

        WaveDataProvider()
            : mWaveFormat(WAVE_FORMAT_MONO8),
            mChannels(0),
            mSamplesPerSec(0),
            mBitsPerSample(0)
        {
        }

        virtual ~WaveDataProvider()
        {
        }

        WAVE_FORMAT GetWaveFormat() const
        {
            return mWaveFormat;
        }

        UInt32 GetChannels() const
        {
            return mChannels;
        }

        UInt32 GetSamplePerSec() const
        {
            return mSamplesPerSec;
        }

        UInt32 GetBitsPerSample() const
        {
            return mBitsPerSample;
        }

        virtual bool IsEOF() const
        {
            return true;
        }

        virtual void Seek(Float32 time)
        {
        }

        virtual bool IsStreaming() const
        {
            return false;
        }

        virtual Int32 StreamWaveData(UInt32 size)
        {
            return 0;
        }

        virtual UInt8* GetWaveData() = 0;
        virtual UInt32 GetWaveDataSize() const = 0;
    };

    class DFX_EXPORT StreamingWaveDataProvider : public WaveDataProvider
    {
    protected:

        UInt8Array  mWaveData;
        UInt32      mWaveDataSize;

    public:

        StreamingWaveDataProvider()
            : mWaveDataSize(0)
        {
        }

        virtual ~StreamingWaveDataProvider()
        {
        }
        
        virtual bool IsStreaming() const
        {
            return true;
        }

        virtual UInt8* GetWaveData()
        {
            return &mWaveData[0];
        }

        virtual UInt32 GetWaveDataSize() const
        {
            return mWaveDataSize;
        }
    };

    class DFX_EXPORT DecodingProvider : public StreamingWaveDataProvider
    {
    protected:

        bool    mLoop;
        bool    mEOF;

    public:

        DecodingProvider()
            : mLoop(false), mEOF(false)
        {
        }

        virtual ~DecodingProvider()
        {
        }

        virtual bool IsEOF() const
        {
            return mEOF;
        }

        virtual Int32 StreamWaveData(UInt32 size);

    protected:

        virtual Int32 ReadFromFile(UInt32 size, UInt32 bytesRead) = 0;
    };
}

# endif